package com.hoshiicloud.gateway.controller;

import com.google.gson.Gson;
import com.hoshiicloud.common.rpc.Response;
import com.hoshiicloud.gateway.config.UrlModulesConfig;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

/**
 * @author MarkerCCC
 * @date 2019-09-20 - 09:52
 */
@Slf4j
@RestController
@RequestMapping("/getUrlModulesController")
public class GetUrlModulesController {

    private final UrlModulesConfig urlModulesConfig;

    private final LoadBalancerClient loadBalancerClient;

    private final RestTemplate restTemplate;

    public GetUrlModulesController(UrlModulesConfig urlModulesConfig,
            LoadBalancerClient loadBalancerClient, RestTemplate restTemplate) {
        this.urlModulesConfig = urlModulesConfig;
        this.loadBalancerClient = loadBalancerClient;
        this.restTemplate = restTemplate;
    }

    /**
     * 得到所有的路径映射, 详情配置看urlModulesConfig
     *
     * @return Map
     */
    @GetMapping("getAllUrlModules")
    public Response<Map<String, Map<String, String>>> getUrlModules() {
        List<String> moduleNameList = urlModulesConfig.getModuleName();
        Map<String, Map<String, String>> resultMap = new HashMap<>(16);
        for (String moduleName : moduleNameList) {
            ServiceInstance serviceInstance = loadBalancerClient.choose(moduleName);
            String requestUrl = String
                    .format("http://%s:%s", serviceInstance.getHost(), serviceInstance.getPort() + "/moduleController/getRequestUrl");
            log.error(requestUrl);
            LinkedMultiValueMap<String, String> header = new LinkedMultiValueMap<>();
            LinkedMultiValueMap<String, String> body = new LinkedMultiValueMap<>();
            HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(body, header);
            //设置restTemplate远程调用时候，对400和401不让报错，正确返回数据
            restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
                @Override
                public void handleError(ClientHttpResponse response) throws IOException {
                    if (response.getRawStatusCode() != 400 && response.getRawStatusCode() != 401) {
                        super.handleError(response);
                    }
                }
            });
            ResponseEntity<Map> exchange = restTemplate
                    .exchange(requestUrl, HttpMethod.GET, httpEntity, Map.class);
            Map<String, List<String>> bodyMap = exchange.getBody();
            Object data = bodyMap.get("data");
            LinkedHashMap<String, String> linkedMultiValueMap = (LinkedHashMap<String, String>) data;
            resultMap.put(moduleName, linkedMultiValueMap);
        }
        return Response.data(resultMap);
    }

    /**
     * 多个moduleNameList
     *
     * @param moduleNameList 多个moduleNameList
     * @return Map
     */
    @GetMapping("getMultipleUrlModules")
    public Response<Map<String, Map<String, String>>> getMultipleUrlModules(@RequestBody List<String> moduleNameList) {
        Map<String, Map<String, String>> resultMap = new HashMap<>(16);
        for (String moduleName : moduleNameList) {
            ServiceInstance serviceInstance = loadBalancerClient.choose(moduleName);
            String requestUrl = String
                    .format("http://%s:%s", serviceInstance.getHost(), serviceInstance.getPort() + "/moduleController/getRequestUrl");
            log.error(requestUrl);
            LinkedMultiValueMap<String, String> header = new LinkedMultiValueMap<>();
            LinkedMultiValueMap<String, String> body = new LinkedMultiValueMap<>();
            HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(body, header);
            //设置restTemplate远程调用时候，对400和401不让报错，正确返回数据
            restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
                @Override
                public void handleError(ClientHttpResponse response) throws IOException {
                    if (response.getRawStatusCode() != 400 && response.getRawStatusCode() != 401) {
                        super.handleError(response);
                    }
                }
            });
            ResponseEntity<Map> exchange = restTemplate
                    .exchange(requestUrl, HttpMethod.GET, httpEntity, Map.class);
            Map<String, List<String>> bodyMap = exchange.getBody();
            Object data = bodyMap.get("data");
            LinkedHashMap<String, String> linkedMultiValueMap = (LinkedHashMap<String, String>) data;
            resultMap.put(moduleName, linkedMultiValueMap);
        }
        return Response.data(resultMap);
    }
}
